"""高德地图API服务模块"""
import logging
import requests
import json
from config.mcp_config import AMAP
# 改为导入主MCP实例
from mcp_server import mcp
from typing import Dict, Any, Optional, Union
 
logger = logging.getLogger('AMapService')

# 定义常量
AMAP_API_KEY: str = AMAP.get("AMAP_API_KEY") or ""
AMAP_BASE_URL: str = "https://restapi.amap.com/v3"
DEFAULT_CITY: str = AMAP.get("AMAP_CITY_NAME") or "西安"
DEFAULT_COORDINATES: str = AMAP.get("AMAP_CITY_LONGITUDE") or "109.007697,34.384069"


def normalize_location(location: str) -> str:
    """标准化位置信息
    起点默认使用 DEFAULT_COORDINATES，城市默认使用西安
    """
    if not location:
        logger.info(f"位置为空，使用默认坐标: {DEFAULT_COORDINATES}")
        return DEFAULT_COORDINATES
    
    # 处理常见的位置描述
    location_lower = location.lower().strip()
    
    if location_lower in ["当前位置", "我的位置", "这里", "现在的位置", "我在的地方"]:
        logger.info(f"将'{location}'转换为默认坐标: {DEFAULT_COORDINATES}")
        return DEFAULT_COORDINATES
    
    # 如果位置中不包含指定城市名，且不包含西安，则添加西安前缀
    if not any(city in location for city in ["北京", "上海", "广州", "深圳", "杭州", "南京", "武汉", "成都", "重庆", "天津", "苏州"]):
        if "西安" not in location:
            location = f"西安{location}"
            logger.info(f"为地点添加城市前缀: {location}")
    
    return location


def get_geocode(address: str) -> str:
    """使用高德地图地理编码API将地址转换为经纬度"""
    try:
        geocode_url = f"{AMAP_BASE_URL}/geocode/geo"
        params = {
            "key": AMAP_API_KEY,
            "address": address
        }
        response = requests.get(geocode_url, params=params, timeout=10)
        response.raise_for_status()
        data = response.json()
        if data.get("status") == "1" and data.get("geocodes"):
            location = data["geocodes"][0].get("location")
            return location or DEFAULT_COORDINATES
    except Exception as e:
        logger.error(f"地理编码失败: {e}")
    return DEFAULT_COORDINATES

# 查天气
@mcp.tool()
def weather(city: str) -> Union[Dict[str, Any], str]:
    """For querying the weather of a city, use this tool. The input is the name of the city."""
    if not city:
        city = AMAP.get("AMAP_CITY_NAME") or "西安"
    
    
    try:
        logger.info(f"使用高德地图API查询{city}天气")
        
        # 高德天气API URL
        weather_url = f"{AMAP_BASE_URL}/weather/weatherInfo"
        
        # 请求参数
        params = {
            "key": AMAP_API_KEY,
            "city": city,
            "extensions": "base"  # base:实况天气, all:预报天气
        }
        
        # 发送请求
        response = requests.get(weather_url, params=params, timeout=10)
        response.raise_for_status()
        
        data = response.json()
        logger.info(f"高德API响应: {data}")
        
        # 检查API响应状态
        if data.get("status") == "1" and data.get("lives"):
            weather_info = data["lives"][0]
            
            city_name = weather_info.get("city", city)
            weather_desc = weather_info.get("weather", "未知")
            temperature = weather_info.get("temperature", "未知")
            humidity = weather_info.get("humidity", "未知")
            wind_direction = weather_info.get("winddirection", "")
            wind_power = weather_info.get("windpower", "")
            report_time = weather_info.get("reporttime", "")
            
            # 格式化天气信息
            result = f"🌤️ {city_name}实时天气：{weather_desc}，温度{temperature}°C，湿度{humidity}%"
            
            if wind_direction and wind_power:
                result += f"，{wind_direction}风{wind_power}级"
            
            if report_time:
                result += f"\n📅 更新时间：{report_time}"
            
            result += " (高德地图数据)"
            
            logger.info(f"高德天气查询成功: {result}")
            return {"success": True, "result": weather_info}
            
        else:
            # API返回错误
            error_msg = data.get("info", "未知错误")
            logger.error(f"高德天气API错误: {error_msg}")
            return f"抱歉，无法获取{city}的天气信息：{error_msg}"
            
    except requests.exceptions.RequestException as e:
        logger.error(f"高德天气API请求失败: {e}")
        return f"抱歉，天气服务暂时不可用，请稍后重试"
    except json.JSONDecodeError as e:
        logger.error(f"高德天气API响应解析失败: {e}")
        return f"抱歉，天气数据解析失败，请稍后重试"
    except Exception as e:
        logger.error(f"高德天气查询异常: {e}")
        return f"抱歉，天气查询出现异常，请稍后重试"

# 预报    
@mcp.tool()
def forecast(city: str) -> Union[Dict[str, Any], str]:
    """For querying the forecast of a city, use this tool. The input is the name of the city."""
    if not city:
        city = DEFAULT_CITY
    
    try:
        logger.info(f"使用高德地图API查询{city}天气预报")
        
        weather_url = f"{AMAP_BASE_URL}/weather/weatherInfo"
        
        params = {
            "key": AMAP_API_KEY,
            "city": city,
            "extensions": "all"  # 获取预报天气
        }
        
        response = requests.get(weather_url, params=params, timeout=10)
        response.raise_for_status()
        
        data = response.json()
        
        if data.get("status") == "1" and data.get("forecasts"):
            forecast_info = data["forecasts"][0]
            city_name = forecast_info.get("city", city)
            casts = forecast_info.get("casts", [])
            
            if casts:
                result = f"🌤️ {city_name}天气预报：\n"
                for i, cast in enumerate(casts[:3]):  # 显示前3天
                    date = cast.get("date", "")
                    dayweather = cast.get("dayweather", "")
                    nightweather = cast.get("nightweather", "")
                    daytemp = cast.get("daytemp", "")
                    nighttemp = cast.get("nighttemp", "")
                    
                    result += f"📅 {date}: {dayweather}转{nightweather}，{nighttemp}°C~{daytemp}°C\n"
                
                result += "(高德地图数据)"
                logger.info(f"天气预报查询成功: {result}")
                return {"success": True, "result": result}
        
        error_msg = data.get("info", "未知错误")
        logger.error(f"高德天气预报API错误: {error_msg}")
        return {"success": False, "result": f"抱歉，无法获取{city}的天气预报：{error_msg}"}
        
    except requests.exceptions.RequestException as e:
        logger.error(f"天气预报API请求失败: {e}")
        return {"success": False, "result": f"抱歉，天气预报服务暂时不可用，请稍后重试"}
    except Exception as e:
        logger.error(f"天气预报查询失败: {e}")
        return {"success": False, "result": f"抱歉，天气预报查询出现异常，请稍后重试"}

# 路线规划工具
@mcp.tool()
def route_planner(arguments: Optional[Dict[str, Any]] = None) -> Union[Dict[str, Any], str]:
    """使用高德地图API获取路线规划
    起点默认使用 DEFAULT_COORDINATES，城市默认使用西安
    """
    if not arguments or not isinstance(arguments, dict):
        return {"success": False, "result": "抱歉，路线规划需要终点信息"}

    # 强制使用默认坐标作为起点
    origin = DEFAULT_COORDINATES
    logger.info(f"强制使用默认坐标作为起点: {DEFAULT_COORDINATES}")
    
    destination = arguments.get("destination", "")
    strategy = arguments.get("strategy", "fastest")
    
    # 处理终点
    if not destination:
        return {"success": False, "result": "抱歉，请提供终点信息"}
    
    destination = normalize_location(destination)
    destination = get_geocode(destination)
    
    try:
        logger.info(f"使用高德地图API规划路线：{origin} -> {destination}, 策略: {strategy}")
        
        # 路线规划策略映射
        strategy_map = {
            "fastest": "0",      # 速度优先（时间）
            "shortest": "1",     # 距离优先
            "avoid_traffic": "2", # 避免拥堵
            "no_highway": "3",   # 不走高速
            "save_money": "4"    # 省钱（不走收费路段）
        }
        
        strategy_code = strategy_map.get(strategy, "0")
        
        # 高德路线规划API URL
        route_url = f"{AMAP_BASE_URL}/direction/driving"
        
        # 请求参数
        params = {
            "key": AMAP_API_KEY,
            "origin": origin,
            "destination": destination,
            "strategy": strategy_code,
            "extensions": "all",  # 返回详细信息
            "output": "json"
        }
        
        logger.info(f"路线规划请求参数: origin={origin}, destination={destination}, strategy={strategy_code}")
        
        # 发送请求
        response = requests.get(route_url, params=params, timeout=15)
        response.raise_for_status()
        
        data = response.json()
        logger.info(f"高德路线规划API响应状态: {data.get('status')}, 信息: {data.get('info')}")
        
        # 检查API响应状态
        if data.get("status") == "1" and data.get("route"):
            route_info = data["route"]
            paths = route_info.get("paths", [])
            
            # 格式化起点显示
            origin_display = f"{DEFAULT_CITY}当前位置" if origin == DEFAULT_COORDINATES else arguments.get("origin", "")
            
            if paths:
                # 获取第一条路线（推荐路线）
                path = paths[0]
                
                # 基本信息
                distance = path.get("distance", "0")  # 距离（米）
                duration = path.get("duration", "0")  # 时间（秒）
                tolls = path.get("tolls", "0")        # 过路费（元）
                traffic_lights = path.get("traffic_lights", "0")  # 红绿灯数量
                
                # 转换单位
                distance_km = round(float(distance) / 1000, 1) if distance != "0" else 0
                duration_min = round(float(duration) / 60, 0) if duration != "0" else 0
                
                # 策略名称
                strategy_names = {
                    "fastest": "速度优先",
                    "shortest": "距离优先", 
                    "avoid_traffic": "避免拥堵",
                    "no_highway": "不走高速",
                    "save_money": "省钱路线"
                }
                
                strategy_name = strategy_names.get(strategy, "推荐路线")
                
                # 格式化路线信息
                result = f"🗺️ 路线规划（{strategy_name}）：\n"
                result += f"📍 起点：{origin_display}\n"
                result += f"📍 终点：{arguments.get('destination', '')}\n"
                result += f"📏 距离：{distance_km}公里\n"
                result += f"⏱️ 预计时间：{int(duration_min)}分钟\n"
                
                if tolls and tolls != "0":
                    result += f"💰 过路费：{tolls}元\n"
                
                if traffic_lights and traffic_lights != "0":
                    result += f"🚦 红绿灯：{traffic_lights}个\n"
                
                # 获取详细步骤（前几步）
                steps = path.get("steps", [])
                if steps:
                    result += f"\n🛣️ 主要路段：\n"
                    for i, step in enumerate(steps[:5]):  # 显示前5个主要步骤
                        instruction = step.get("instruction", "")
                        road_name = step.get("road", "")
                        step_distance = step.get("distance", "0")
                        
                        if instruction and road_name:
                            step_distance_km = round(float(step_distance) / 1000, 1) if step_distance != "0" else 0
                            result += f"{i+1}. {instruction}，沿{road_name}行驶{step_distance_km}公里\n"
                
                result += "\n(高德地图数据)"
                
                logger.info(f"路线规划查询成功")
                return {"success": True, "result": result}
            else:
                return {"success": False, "result": f"抱歉，未找到从{origin_display}到{arguments.get('destination', '')}的路线"}
                
        else:
            # API返回错误
            error_msg = data.get("info", "未知错误")
            logger.error(f"高德路线规划API错误: {error_msg}")
            
            # 提供更友好的错误提示
            if error_msg == "INVALID_PARAMS":
                return {"success": False, "result": f"抱歉，无法识别地点'{arguments.get('destination', '')}'。请提供更具体的地址，比如：\n• 西安北辰村\n• 西安市雁塔区北辰村\n• 或者具体的街道地址"}
            else:
                return {"success": False, "result": f"抱歉，路线规划失败：{error_msg}"}
            
    except requests.exceptions.RequestException as e:
        logger.error(f"高德路线规划API请求失败: {e}")
        return {"success": False, "result": f"抱歉，路线规划服务暂时不可用，请稍后重试"}
    except json.JSONDecodeError as e:
        logger.error(f"高德路线规划API响应解析失败: {e}")
        return {"success": False, "result": f"抱歉，路线数据解析失败，请稍后重试"}
    except Exception as e:
        logger.error(f"路线规划查询异常: {e}")
        return {"success": False, "result": f"抱歉，路线规划出现异常，请稍后重试"}

# POI搜索工具
@mcp.tool()
def poi_search(keyword: str, city: Optional[str] = None, types: str = "", radius: int = 5000) -> Dict[str, Any]:
    """使用高德地图API搜索地点，如美食、厕所、加油站等。
    
    Args:
        keyword: 搜索关键词（如：美食、厕所、加油站）
        city: 搜索城市，默认使用配置的城市
        types: POI类型编码，可选（如：050000为餐饮服务，010000为汽车服务）
        radius: 搜索半径（米），默认5000米
    
    Returns:
        dict: 包含搜索结果的字典
    """
    # 如果没有提供城市，使用默认城市
    if not city:
        city = DEFAULT_CITY
    
    try:
        logger.info(f"使用高德地图API在{DEFAULT_COORDINATES}周围{radius}米内搜索{keyword}")
        
        # 使用周边搜索API
        poi_url = f"{AMAP_BASE_URL}/place/around"
        
        # 请求参数
        params = {
            "key": AMAP_API_KEY,
            "location": DEFAULT_COORDINATES,  # 使用默认坐标作为中心点
            "keywords": keyword,
            "radius": radius,  # 搜索半径
            "extensions": "base",  # 基本信息
            "page": 1,
            "offset": 10,  # 返回10个结果
            "output": "json"
        }
        
        # 如果提供了types参数，则添加到请求中
        if types:
            params["types"] = types
        
        # 发送请求
        response = requests.get(poi_url, params=params, timeout=10)
        response.raise_for_status()
        
        data = response.json()
        logger.info(f"高德POI周边搜索API响应: {data}")
        
        # 检查API响应状态
        if data.get("status") == "1" and data.get("pois"):
            pois = data["pois"]
            
            # 格式化搜索结果
            result = f"📍 在{DEFAULT_CITY}当前位置周围{radius}米内搜索到的{keyword}：\n"
            
            for i, poi in enumerate(pois[:5], 1):  # 显示前5个结果
                name = poi.get("name", "未知")
                address = poi.get("address", "地址未知")
                location = poi.get("location", "")
                tel = poi.get("tel", "")
                distance = poi.get("distance", "")
                
                result += f"{i}. {name}\n"
                result += f"   地址：{address}\n"
                if distance:
                    result += f"   距离：约{int(distance)}米\n"
                if tel:
                    result += f"   电话：{tel}\n"
                result += "\n"
            
            result += "(高德地图数据)"
            
            logger.info(f"POI周边搜索成功: {keyword}")
            return {"success": True, "result": result}
            
        else:
            # API返回错误
            error_msg = data.get("info", "未知错误")
            logger.error(f"高德POI周边搜索API错误: {error_msg}")
            return {"success": False, "result": f"抱歉，无法在{DEFAULT_CITY}当前位置周围搜索到{keyword}：{error_msg}"}
            
    except requests.exceptions.RequestException as e:
        logger.error(f"高德POI周边搜索API请求失败: {e}")
        return {"success": False, "result": f"抱歉，搜索服务暂时不可用，请稍后重试"}
    except json.JSONDecodeError as e:
        logger.error(f"高德POI周边搜索API响应解析失败: {e}")
        return {"success": False, "result": f"抱歉，搜索数据解析失败，请稍后重试"}
    except Exception as e:
        logger.error(f"POI周边搜索异常: {e}")
        return {"success": False, "result": f"抱歉，搜索出现异常，请稍后重试"}